{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction\n",
    "This is an example of a Python notebook used to train a model (K-means Cluster) and then export it as PMML so that it can be easily integrated with additional decision logic."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Use case: purchase recommendations\n",
    "In this example end user has bought a series of items (Book, Car, PC) and we want to predict recommendation for his/her next purchase"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prerequisite\n",
    "To run this notebook you need to have:\n",
    "- Python 3 https://www.python.org/downloads/\n",
    "- Pip https://pypi.org/project/pip/\n",
    "- jupyter https://jupyter.org/ (`pip install jupyterlab`)\n",
    "\n",
    "Install dependencies:\n",
    "- pandas\n",
    "- scikit-learn\n",
    "- numpy\n",
    "- nyoka\n",
    "- matplotlib\n",
    "\n",
    "All of them can be installed cloning this repo and using command `pip install -r ./binder/requirements.txt`\n",
    "\n",
    "Finally start the environment using the command `jupyter notebook`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import preprocessing\n",
    "from sklearn.cluster import KMeans\n",
    "from sklearn.decomposition import PCA\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.pipeline import Pipeline\n",
    "from nyoka import skl_to_pmml\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 1 - Load and prepare data\n",
    "Data are usually available as unstructure files with text (csv) or binary (parquet, avro) format and there are many libraries to load them from a local or remote storage.\n",
    "\n",
    "After the loading step it is quite common to perform some preparation/cleanup actions: check domain boundaries, handle missing values, normalize strings, convert enumaration to number, etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "pycharm": {
     "is_executing": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>type</th>\n",
       "      <th>buyed_items</th>\n",
       "      <th>type_index</th>\n",
       "      <th>buyed_items_indexes</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Book</td>\n",
       "      <td>[Book-1, Book-2, Book-3, Book-5, Book-8, Book-...</td>\n",
       "      <td>0</td>\n",
       "      <td>[0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>PC</td>\n",
       "      <td>[Book-8, Car-3, Car-4, Car-7, PC-0, PC-1, PC-2...</td>\n",
       "      <td>2</td>\n",
       "      <td>[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Book</td>\n",
       "      <td>[Book-1, Book-5, Book-6, Book-7, Book-8, Book-...</td>\n",
       "      <td>0</td>\n",
       "      <td>[0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Car</td>\n",
       "      <td>[Car-0, Car-1, Car-2, Car-3, Car-4, Car-5, Car-8]</td>\n",
       "      <td>1</td>\n",
       "      <td>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>PC</td>\n",
       "      <td>[Car-7, PC-0, PC-2, PC-3, PC-4, PC-5, PC-7, PC-8]</td>\n",
       "      <td>2</td>\n",
       "      <td>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   type                                        buyed_items  type_index  \\\n",
       "0  Book  [Book-1, Book-2, Book-3, Book-5, Book-8, Book-...           0   \n",
       "1    PC  [Book-8, Car-3, Car-4, Car-7, PC-0, PC-1, PC-2...           2   \n",
       "2  Book  [Book-1, Book-5, Book-6, Book-7, Book-8, Book-...           0   \n",
       "3   Car  [Car-0, Car-1, Car-2, Car-3, Car-4, Car-5, Car-8]           1   \n",
       "4    PC  [Car-7, PC-0, PC-2, PC-3, PC-4, PC-5, PC-7, PC-8]           2   \n",
       "\n",
       "                                 buyed_items_indexes  \n",
       "0  [0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, ...  \n",
       "1  [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, ...  \n",
       "2  [0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, ...  \n",
       "3  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, ...  \n",
       "4  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv('input_data.csv')\n",
    "# splitting buyed_items string to arrays\n",
    "df.buyed_items = df.buyed_items.str[1:-1].str.replace(\"'\",'').str.replace(\",\",'').str.split(' ')\n",
    "# splitting buyed_customer_items_id string to arrays\n",
    "df.buyed_items_indexes = df.buyed_items_indexes.str[1:-1].str.replace(\"'\",'').str.replace(\",\",'').str.split(' ')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "# Step 2 - Prepare training set and test set\n",
    "When a model is trained, it is important to use different set of data to train and test it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "pycharm": {
     "is_executing": false,
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# load required columns\n",
    "inputs = df['buyed_items_indexes']\n",
    "outputs = df['type']\n",
    "# splitting buyed_customer_items_id array to multiple columns\n",
    "inputs_multicolumn  = pd.DataFrame(inputs.tolist(), index=inputs.index)\n",
    "            \n",
    "# splitting data in training/test   \n",
    "test_size = 0.4             # percentage of data used to create test set\n",
    "random_state = 23           # fixed seed to make randomization reproducible\n",
    "input_train, input_test, output_train, output_test = train_test_split(inputs_multicolumn, outputs, test_size=test_size, random_state=random_state)             \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "\n",
    "# Step 3 - Train the model\n",
    "There are many different models that can be used. In this example we will use a KMeans cluster classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "pycharm": {
     "is_executing": false,
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "pipeline = Pipeline([\n",
    "    (\"classifier\", KMeans(n_clusters=3, random_state=0))\n",
    "])\n",
    "trained_model = pipeline.fit(input_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 4 - Test the mode"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are multiple way to test the model, first of all you should test it using test data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "pycharm": {
     "is_executing": false,
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "model_score: -1626.7613477124366\n"
     ]
    }
   ],
   "source": [
    "model_score = trained_model.score(input_test)\n",
    "print(\"model_score: \" + str(model_score))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note: Pay attention to overfitting problem ( https://en.wikipedia.org/wiki/Overfitting )  while you train and test your model. For example a score of 0.99 or similar is an important sign of a probable overfit."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Additionally you can print to visually compare predicted data with real data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "pycharm": {
     "is_executing": false,
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cluster prediction</th>\n",
       "      <th>buyer group</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>519</th>\n",
       "      <td>1</td>\n",
       "      <td>Car</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>837</th>\n",
       "      <td>2</td>\n",
       "      <td>Book</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>208</th>\n",
       "      <td>0</td>\n",
       "      <td>PC</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>525</th>\n",
       "      <td>1</td>\n",
       "      <td>Car</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>978</th>\n",
       "      <td>0</td>\n",
       "      <td>PC</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     cluster prediction buyer group\n",
       "519                   1         Car\n",
       "837                   2        Book\n",
       "208                   0          PC\n",
       "525                   1         Car\n",
       "978                   0          PC"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predictions = trained_model.predict(input_test)\n",
    "results = pd.DataFrame({'cluster prediction': predictions.astype(int), 'buyer group': output_test})\n",
    "results.head()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another approach is to plot predicted data on chart"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#reduce the number of dimensions so that we can visualize the results using a 2D Scatter plot.\n",
    "pca = PCA(2)\n",
    "#Transform the data\n",
    "df = pca.fit_transform(input_test)\n",
    "\n",
    "df.shape\n",
    "\n",
    "#Initialize the class object\n",
    "kmeans =  KMeans(n_clusters=3, random_state=0)\n",
    "\n",
    "#predict the labels of clusters.\n",
    "label = kmeans.fit_predict(df)\n",
    "\n",
    "filtered_label0 = df[label == 0]\n",
    "filtered_label1 = df[label == 1]\n",
    "filtered_label2 = df[label == 2]\n",
    "\n",
    "#plotting the results\n",
    "plt.scatter(filtered_label0[:,0] , filtered_label0[:,1], label = 0)\n",
    "plt.scatter(filtered_label1[:,0] , filtered_label1[:,1], label = 1)\n",
    "plt.scatter(filtered_label2[:,0] , filtered_label2[:,1], label = 2)\n",
    "plt.legend()\n",
    "plt.show()\n",
    "\n",
    "#plotting centroids\n",
    "#Getting the Centroids\n",
    "centroids = kmeans.cluster_centers_\n",
    "u_labels = np.unique(label)\n",
    " \n",
    "#plotting the results:\n",
    " \n",
    "for i in u_labels:\n",
    "    plt.scatter(df[label == i , 0] , df[label == i , 1] , label = i)\n",
    "plt.scatter(centroids[:,0] , centroids[:,1] , s = 80, color = 'k')\n",
    "plt.legend()\n",
    "plt.show()\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Scoring and visualization are just simple ways to test the trained model. They are usually not enough for real world use cases.\n",
    "\n",
    "There are advanced way to analyze how the model is performing (i.e. ROC) and there are many other aspects to consider: fairness, explanability, interpretability.\n",
    "\n",
    "Additional resources:\n",
    "- https://en.wikipedia.org/wiki/Receiver_operating_characteristic\n",
    "- https://christophm.github.io/interpretable-ml-book/"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Step 5 - Save the model as PMML\n",
    "When your are happy with your model you can export it as PMML."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "features = inputs_multicolumn.columns\n",
    "skl_to_pmml(trained_model,col_names=features,target_name=\"buy_group\",pmml_f_name=\"cluster_buyer_predictor.pmml\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "metadata": {
     "collapsed": false
    },
    "source": []
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
